package define

import (
	"encoding/json"
	"fmt"
	"math/rand"
)

const (
	// for agent
	StatusNotReady = `notReady`
	StatusUnKnown  = `unknown`

	// for instance
	StatusInConfiguration = "InConfiguration"
	StatusInScheduling    = "InScheduling"
	StatusPending         = "Pending"
	StatusReady           = "Ready"
	StatusPause           = "Pause"
	StatusError           = "Error"
	StatusTerminating     = "Terminating"
	StatusTerminated      = "Terminated"
)

func DefaultInstance() *Instance {
	i := &Instance{
		Config: DefaultConfig(),
	}

	i.StateInfo.Node = "glue node1"
	i.StateInfo.Guid = "glue guid"
	i.StateInfo.State = StatusInConfiguration

	i.Instance.Name = i.Config.BaseInfo.Name + ".001"
	i.Instance.Level = "0"
	i.Instance.PGuid = i.StateInfo.Guid
	i.Instance.CGuid = []string{"children1", "children2"}
	return i
}

type Instance struct {
	Config    *Config      `json:"config" yaml:"config"`
	StateInfo stateInfo    `json:"state" yaml:"state"`
	Instance  instanceInfo `json:"instance" yaml:"instance"`
}

func (r *Instance) Clone() *Instance {
	c := &Instance{
		Config:    r.Config.Clone(),
		StateInfo: r.StateInfo,
		Instance:  r.Instance.Clone(),
	}
	return c
}

type stateInfo struct {
	State string `json:"state" yaml:"state"`
	Guid  string `json:"guid" yaml:"guid"`
	Node  string `json:"node" yaml:"node"`
}

type instanceInfo struct {
	Name  string   `json:"name" yaml:"name"`
	Level string   `json:"level" yaml:"level"`
	PGuid string   `json:"pguid" yaml:"pguid"`
	CGuid []string `json:"cguid" yaml:"cguid"`
}

func (r instanceInfo) Clone() instanceInfo {
	cGuids := make([]string, len(r.CGuid))
	copy(cGuids, r.CGuid)

	c := r
	c.CGuid = cGuids
	return c
}

func (r instanceInfo) EnCodeCGuids() string {
	bts, _ := json.Marshal(r.CGuid)
	return string(bts)
}

func (r instanceInfo) DeCodeCGuids(cGuids string) {
	if err := json.Unmarshal([]byte(cGuids), &r.CGuid); err != nil {
		panic(err)
	}
}

func RandSuffix(n int) string {
	randBytes := make([]byte, n)
	_, _ = rand.Read(randBytes)
	return fmt.Sprintf("%x", randBytes)
}
